package com.example.educational.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.educational.controller.utils.Code;
import com.example.educational.controller.utils.SystemException;
import com.example.educational.entity.Attachment;
import com.example.educational.entity.Corporate;
import com.example.educational.entity.NoticeReceived;
import com.example.educational.entity.User;
import com.example.educational.entity.VerCode.AesException;
import com.example.educational.entity.VerCode.WXBizMsgCrypt;
import com.example.educational.service.CorporateService;
import com.example.educational.service.InnerAppService;
import com.example.educational.utils.PrintUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Service
public class CorporateServiceImpl implements CorporateService {

    @Autowired
    Corporate corporate;

    @Autowired
    InnerAppService innerAppService;


    @Override
    public String getToken4InnerApp(int index) {
        // 获取企业内部应用Token
        File file = new File(PrintUtil.JoinStr(String.valueOf(index), "_InnerAPP", ".txt"));
        return getToken(file, 0);
    }

    @Override
    public String getToken4AddrBook() {
        // 获取企业通讯录Token
        File file = new File(PrintUtil.JoinStr("corporateAddrBook", ".txt"));
        return getToken(file, 520);
    }

    private String getToken(File file, int index) {
        // 1.读取accessToken
        String accessToken = "";
        long nowTime = System.currentTimeMillis();
        // 2.判断是否首次运行应用
        boolean flag = file.exists();
        if (flag) {
            String result = FileUtil.readString(file, StandardCharsets.UTF_8);
            String[] strings = result.split(",");
            // 3.判断token是否过期
            if (nowTime - Long.parseLong(strings[1]) < 7200000) {
                System.out.println("token，已重新读取~~");
                return strings[0];
            }
        }

        // 4.重新获取并写入文件
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("corpid", corporate.getCorpId());
        if (index > 500) {
            paramMap.put("corpsecret", corporate.getAddressSecret());
        } else {
            paramMap.put("corpsecret", corporate.getInnerApp().get(index).getCorpSecret());

        }
        String httpF = PrintUtil.JoinStr(corporate.getHttp(), "gettoken?");
        String response = HttpUtil.get(httpF, paramMap);
        JSONObject parsedObj = JSONUtil.parseObj(response);
        Object errCode = parsedObj.get("errcode");
        // 5.判断企业微信是否正确
        if ("0".equals(errCode.toString())) {
            accessToken = parsedObj.get("access_token").toString();
            FileUtil.writeString(
                    PrintUtil.JoinStr(accessToken, ",", String.valueOf(nowTime)),
                    file, StandardCharsets.UTF_8);
        } else {
            throw new SystemException(Code.err, parsedObj.get("errmsg").toString());
        }

        System.out.println("token获取完成~~");
        return accessToken;
    }

    @Override
    public Boolean pushNotice2Everyone(NoticeReceived noticeReceived) {
        // 1.获取token
        String accessToken = getToken4InnerApp(0);
        String name = noticeReceived.getName();
        String title = noticeReceived.getTitle();
        String category = noticeReceived.getCategory();
        String releaseDate = noticeReceived.getReleaseDate();
        DateTime dateTime = DateUtil.parse(releaseDate);
        String taskId = String.valueOf(dateTime.getTime());
        String imgSrc = noticeReceived.getImgSrc();
        ArrayList<Attachment> fileSrc = noticeReceived.getFileSrc();
        Boolean result = innerAppService.sendMessageByTextNotice("@all", accessToken, name, title, category, releaseDate, imgSrc, taskId, fileSrc);
        return Boolean.TRUE;
    }

    @Override
    public Boolean pushNotice2User(NoticeReceived noticeReceived, ArrayList<String> userIdList) {
        // 1.获取accessToken
        String accessToken = getToken4InnerApp(0);
        // 2.转换用户Id列表
        String resultIds = String.join("|", userIdList);
        // 3.推送消息
        String name = noticeReceived.getName();
        String title = noticeReceived.getTitle();
        String category = noticeReceived.getCategory();
        String releaseDate = noticeReceived.getReleaseDate();
        DateTime dateTime = DateUtil.parse(releaseDate);
        String taskId = String.valueOf(dateTime.getTime());
        String imgSrc = noticeReceived.getImgSrc();
        ArrayList<Attachment> fileSrc = noticeReceived.getFileSrc();
        Boolean result = innerAppService.sendMessageByTextNotice(resultIds, accessToken, name, title, category, releaseDate, imgSrc, taskId, fileSrc);
        return Boolean.TRUE;
    }

    @Override
    public ArrayList<User> getUserList() {
        // 1.获取accessToken
        String accessToken = getToken4InnerApp(0);
        // 2.获取所有部门ID
        ArrayList<String> departmentIds = innerAppService.getDepartmentIds(accessToken);
        // 3.获取部门下所有员工，递归获取
        return innerAppService.getInformationFromDepartmentDetail(accessToken, "1");
    }

    @Override
    public User getUserDetail(String code) {
//        // 1.获取accessToken
//        String accessToken = getToken4InnerApp(0);
//        // 1.获取访问用户身份
//        String userTicket = innerAppService.getUserIdentify(accessToken, code);
//        // 2.获取访问用户敏感信息
//        User user = innerAppService.getUserDetailFromWorkChart(accessToken, userTicket);
//        System.out.println("获取用户详细消息成功~~");
//        return user;
        return null;
    }


    @Override
    public String verifyURL(String sVerifyMsgSig, String sVerifyTimeStamp, String sVerifyNonce, String sVerifyEchoStr) throws AesException {
        // 1.获取内部应用接入token
        String sToken = corporate.getInnerApp().get(0).getToken();
        // 2.获取企业ID
        String sCorpID = corporate.getCorpId();
        // 3.验证明文
        String sEncodingAESKey = corporate.getInnerApp().get(0).getEncodingAESKey();
        // 4.完成验证
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
        String sEchoStr = ""; //需要返回的明文
        // 内部应用接入回调服务验证
        try {
            sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,
                    sVerifyNonce, sVerifyEchoStr);
            // 验证URL成功，将sEchoStr返回
        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            throw new RuntimeException(e.getMessage());
        }
        return sEchoStr;
    }

    @Override
    public String reqMsgURL(String sReqMsgSig, String sReqTimeStamp, String sReqNonce, String sReqData) throws AesException {
        // 1.验证数据完整性
        String sToken = corporate.getInnerApp().get(0).getToken();
        String sCorpID = corporate.getCorpId();
        String sEncodingAESKey = corporate.getInnerApp().get(0).getEncodingAESKey();
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
        String sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData);
        return Code.success;
    }

    @Override
    public User checkUserIdentify(String code) {
        User user = new User();
        // 1.获取accessToken
        String accessToken = getToken4InnerApp(0);
        // 2.获取访问用户身份
        HashMap<String, Object> userIdentify = innerAppService.getUserIdentify(accessToken, code);
        // 3.获取访问用户权限
        Object o = userIdentify.get("userid");
        if (o == null) {
            // 3.1用户不存在
            return user;
        } else {
            // 3.2用户存在,获取用户详细信息
            user = innerAppService.getUserDetailByUserId(accessToken, o.toString());
        }
        return user;

    }


}
